package org.msb.accentis.data.pojo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.*;

import org.msb.accentis.data.ClearedType;
import org.msb.accentis.data.TransactionType;

@Entity
@NamedQueries({
		@NamedQuery(name = "Transaction.getAllTransactions", query = "SELECT t FROM Transaction t"),
		@NamedQuery(name = "Transaction.getTransactionDetailsForAccount", query = "SELECT t FROM Transaction t, IN(t.details) td WHERE td.account = :account ORDER BY t.date, t.id"),
		@NamedQuery(name = "Transaction.getTransactionDetailsForAccountUpToDate", query = "SELECT t FROM Transaction t, IN(t.details) td WHERE td.account = :account AND t.date < :today ORDER BY t.date, t.id") })
@Table(name = "Transactions")
public class Transaction extends BaseObject implements Comparable<Transaction> {

	@Temporal(TemporalType.DATE)
	private Date date;

	@Basic
	@Lob
	private String description;

	@Basic
	private String reference;

	@OneToMany(cascade = { CascadeType.ALL })
	private List<TransactionDetail> details = new ArrayList<TransactionDetail>();

	// @OneToOne(cascade=CascadeType.ALL)
	// private Flag flag;

	@Enumerated(EnumType.ORDINAL)
	private ClearedType clearedType = ClearedType.NONE;

	@Enumerated(EnumType.ORDINAL)
	private TransactionType transactionType = TransactionType.SIMPLE;

	@ManyToOne(cascade = { CascadeType.ALL })
	private Payee payee;
	
	public Date getDate() {
		return date;
	}

	public void setDate(Date value) {
		date = value;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String value) {
		description = value;
	}

	public String getReference() {
		return reference;
	}

	public void setReference(String value) {
		reference = value;
	}

	public List<TransactionDetail> getTransactionDetails() {
		return details;
	}

	public BigDecimal getValue() {
		BigDecimal value = BigDecimal.ZERO;
		for (TransactionDetail detail : details)
			value = value.add(detail.getValue());

		return value;
	}

	public BigDecimal getValueForAccount(Account account) {
		BigDecimal value = BigDecimal.ZERO;

		for (TransactionDetail detail : details)
			if (detail.getAccount().equals(account))
				value = value.add(detail.getValue());

		return value;
	}

	// public Flag getFlag() {
	// return flag;
	// }
	//
	// public void setFlag(Flag value) {
	// flag = value;
	// }

	public ClearedType getClearedType() {
		return clearedType;
	}

	public void setClearedType(ClearedType value) {
		clearedType = value;
	}

	public Payee getPayee() {
		return payee;
	}
	
	public void setPayee(Payee value) {
		payee = value;
	}
	
	@Override
	public int compareTo(Transaction o) {
		if (null == o)
			return -1;

		int result = compareToByDate(o.getDate());
		if (0 != result)
			return result;

		return getId() - o.getId();
	}

	private int compareToByDate(Date otherDate) {
		Date thisDate = getDate();
		if (null == thisDate)
			if (null == otherDate)
				return 0;
			else
				return 1;
		else if (null == otherDate)
			return -1;
		else
			return thisDate.compareTo(otherDate);
	}
}
